home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / Book Chapters / 02 - Basic Game Graphics / Amalgam ƒ / OurDlog.c < prev    next >
Encoding:
Text File  |  1995-03-05  |  10.1 KB  |  380 lines  |  [TEXT/MMCC]

  1. //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
  2. //
  3. //    OurDlog.c
  4. //
  5. //    EXPLANATION
  6. //
  7. //    History:
  8. //
  9. //    DATE jb: Written
  10. //
  11. //\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
  12.  
  13.  
  14. //  __#Defines________________________________________________________________________
  15. typedef enum {
  16.     eFindDeepest = 1,
  17.     eFindBiggest,
  18.     eMiniMax,
  19.     eToggleMBar,
  20.     eDemoFade
  21. } etDlogItems;
  22.  
  23. #define kPseudoAlrtID        129
  24.  
  25. //  __#Headers________________________________________________________________________
  26. #include "Amalgam.h"
  27. #include "Menu.h"
  28. #include "FadeGDev.h"
  29. #include "OurDlog.h"
  30.  
  31. //  __#Protos_________________________________________________________________________
  32. //  __ Macros_________________________________________________________________________
  33. //  __ Enums__________________________________________________________________________
  34. //  __ Typedefs_______________________________________________________________________
  35. //  __ Static Protos__________________________________________________________________
  36. static void UpdateOurDialog( void );
  37. static void FindDeepest( void );
  38. static void FindBiggest( void );
  39. static void MiniMaxOurDlog( void );
  40. static void DoFade( void );
  41. static void PseudoAlert( Rect *centerRect );
  42.  
  43. //  __ Extern Globals_________________________________________________________________
  44. //  __ Static Globals_________________________________________________________________
  45. //  __ Functions______________________________________________________________________
  46.  
  47.  
  48. //____ HandleOurDlogEvent __________________________________________________________________________
  49. //
  50. //    This is called from the main event-handling routine when IsDialogEvent says
  51. //    that the event concerns our Modeless dialog. This function handles the
  52. //    event, which it expects to find in the gTheEvent global.
  53. //
  54. //    Returns    void
  55. //
  56. Boolean HandleOurDlogEvent( void )
  57. {
  58. Boolean        dealWithEvent;
  59. DialogPtr    whichDlog;
  60. short        itemHit;
  61. Boolean        handledIt;        //if handledIt, don't let our normal event loop handle the event
  62.  
  63.     handledIt = FALSE;
  64.     
  65.     switch (gTheEvent.what)
  66.     {
  67.         case nullEvent:
  68.         break;
  69.         
  70.         case mouseDown:
  71.         break;
  72.  
  73.         case keyDown:
  74.         case autoKey:
  75.         break;
  76.         
  77.         case updateEvt:
  78.             if ((WindowPtr) gTheEvent.message == gMainDlogPtr)
  79.             {
  80.                 BeginUpdate(gMainDlogPtr);
  81.                 UpdateOurDialog();
  82.                 EndUpdate(gMainDlogPtr);
  83.                 handledIt = TRUE;
  84.             }
  85.         break;
  86.     
  87.     }//switch (gTheEvent.what)
  88.  
  89.     //tell world if we've already dealt with the event.
  90.     if (handledIt)
  91.         return TRUE;
  92.     
  93.     //Process a single modeless dialog event
  94.     dealWithEvent = DialogSelect( &gTheEvent, &whichDlog, &itemHit);
  95.     
  96.     //was there an event to handle occuring in our dialog? If not,
  97.     //pass back FALSE so normal event loop will handle it.
  98.     if ((!dealWithEvent) || (whichDlog != gMainDlogPtr))
  99.         return FALSE;
  100.     
  101.     //the only things we should ever see here are button-hits
  102.     switch (itemHit)
  103.     {
  104.         case eFindDeepest:
  105.             FindDeepest();
  106.         break;
  107.  
  108.         case eFindBiggest:
  109.             FindBiggest();
  110.         break;
  111.  
  112.         case eMiniMax:
  113.             MiniMaxOurDlog();
  114.         break;
  115.  
  116.         case eToggleMBar:
  117.             gUserWantsMenuBar = !gUserWantsMenuBar;
  118.             ToggleMenuBar(gUserWantsMenuBar);
  119.         break;
  120.  
  121.         case eDemoFade:
  122.             DoFade();
  123.         break;
  124.  
  125.         default:
  126.         break;
  127.  
  128.     }//switch itemHit
  129.  
  130.     //return TRUE, since we handled the event ourselves.
  131.     return TRUE;
  132.  
  133. }//HandleOurDlogEvent
  134.  
  135.  
  136. //____ UpdateOurDialog __________________________________________________________________________
  137. //
  138. //    Normally called during an update event and sandwiched
  139. //    between calls to BeginUpdate and EndUpdate.
  140. //
  141. //    Returns    void
  142. //
  143. static void UpdateOurDialog( void )
  144. {
  145.  
  146.     DrawDialog( gMainDlogPtr );
  147.  
  148. }//UpdateOurDialog
  149.  
  150.  
  151. //____ ZoomOurDialog __________________________________________________________________________
  152. //
  153. //    User has clicked in zoombox. If there's only one screen, let system do it's usual
  154. //    job of zooming window; if there's more than one screen, and we're zooming out, 
  155. //    find the screen we're mostly on, and then zoom to fill that screen.
  156. //
  157. //    Dialog can be re-sized to original coordinates by holding down the option key
  158. //    and clicking in the zoom box.
  159. //
  160. //    Value passed is what was originally gotten from FindWindow
  161. //
  162. //    Note that techniques similar to these are used when saving and restoring positons
  163. //    of windows between sessions.
  164. //
  165. void ZoomOurDialog( short thePart )
  166. {
  167. WindowPeek        aPeek;
  168. WStateData        **hWSD;        //state data holds the zoomed and un-zoomed rectangles of
  169.                             //windows
  170. Rect            globalWindowStructRect;
  171. Rect            globalWindowPortRect;
  172. GDHandle        zoomToDevice;
  173. Rect            zoomToRect;
  174.  
  175.     SetPort(gMainDlogPtr);
  176.     
  177.     //Hack: since we're not using a grow box in our dialog, yet we
  178.     //let user zoom it, we need a way of returning to its original
  179.     //size. Here, if the option key is down, we'll re-size the dialog
  180.     //instead of zooming it.
  181.     if (gTheEvent.modifiers & optionKey)
  182.     {
  183.         SizeWindow(gMainDlogPtr,gOriginalDlogPortRect.right - gOriginalDlogPortRect.left,
  184.                                 gOriginalDlogPortRect.bottom - gOriginalDlogPortRect.top,
  185.                                 TRUE);
  186.         return;
  187.     }
  188.         
  189.  
  190.     aPeek = (WindowPeek)gMainDlogPtr;
  191.     hWSD = (WStateData **)aPeek->dataHandle;    //get a handle pointing to WStateData
  192.  
  193.     //if we're zooming out, determine which device we should zoom to; then,
  194.     //create a nice rectangle defining thebounds of that device and stuff
  195.     //it into the windows state data.
  196.     if (inZoomOut == thePart)
  197.     {
  198.         globalWindowStructRect = mWindStructRect(gMainDlogPtr);
  199.  
  200.         globalWindowPortRect = gMainDlogPtr->portRect;        //we'll need this to determine
  201.         LocalToGlobalRect(&globalWindowPortRect);            //size of title bar
  202.  
  203.         zoomToDevice = GetMaxIntersectDevice(globalWindowStructRect);
  204.         zoomToRect = (**zoomToDevice).gdRect;
  205.         if (zoomToDevice == gMainDevice)
  206.             zoomToRect.top += LMGetMBarHeight();
  207.         //make sure there's room for the title bar
  208.         zoomToRect.top += (globalWindowPortRect.top - globalWindowStructRect.top);
  209.  
  210.         InsetRect(&zoomToRect, 8, 8);
  211.         
  212.         (**hWSD).stdState = zoomToRect;
  213.     }
  214.  
  215.     //now that we've fooled with the values ZoomWindow will use,
  216.     //let it do it's thing
  217.     EraseRect(&gMainDlogPtr->portRect);
  218.     ZoomWindow(gMainDlogPtr, thePart, TRUE);
  219.     InvalRect(&gMainDlogPtr->portRect);
  220.  
  221. }//ZoomOurDialog
  222.  
  223.  
  224.  
  225.  
  226. //____ FindDeepest __________________________________________________________________________
  227. //
  228. //    Finds last, deepest screen in GDevice list
  229. //
  230. static void FindDeepest( void )
  231. {
  232. GDHandle            theMaxDevice;
  233. Rect                tempRect;
  234.  
  235.     SetRect( &tempRect, -32768, -32768, 32767, 32767 );
  236.     theMaxDevice = GetMaxDevice(&tempRect);
  237.     
  238.     mAssert(NULL != theMaxDevice);
  239.     mAssert(TestDeviceAttribute(theMaxDevice, screenDevice));
  240.     mAssert(TestDeviceAttribute(theMaxDevice, screenActive));
  241.     
  242.     if (1 == gNumActiveScreens)
  243.     {
  244.         mAssert(theMaxDevice == gMainDevice);
  245.         ParamAString("\pSince there’s only one device, it is also the deepest device");
  246.         
  247.     }
  248.     else
  249.     {
  250.         ParamAString("\pThis is the last, deepest device in the GDevice list.");
  251.     }
  252.         
  253.     tempRect = (**theMaxDevice).gdRect;
  254.     PseudoAlert(&tempRect);
  255.  
  256. }//FindDeepest
  257.  
  258.  
  259.  
  260. //____ FindBiggest __________________________________________________________________________
  261. //
  262. //    Finds last, largest screen in the GDevice list
  263. //
  264. static void FindBiggest( void )
  265. {
  266. GDHandle            theLargestDevice;
  267. Rect                tempRect;
  268.  
  269.     theLargestDevice = GetLargestAreaDevice();
  270.     
  271.     mAssert(NULL != theLargestDevice);
  272.     mAssert(TestDeviceAttribute(theLargestDevice, screenDevice));
  273.     mAssert(TestDeviceAttribute(theLargestDevice, screenActive));
  274.     
  275.     if (1 == gNumActiveScreens)
  276.     {
  277.         mAssert(theLargestDevice == gMainDevice);
  278.         ParamAString("\pSince there’s only one device, it is also the largest device");
  279.     }
  280.     else
  281.     {
  282.         ParamAString("\pThis is the last, largest device found in the GDevice list.");
  283.     }
  284.     
  285.     tempRect = (**theLargestDevice).gdRect;
  286.     PseudoAlert(&tempRect);
  287.  
  288. }//FindBiggest
  289.  
  290.  
  291. //____ MiniMaxOurDlog __________________________________________________________________________
  292. //
  293. //    Toggles the size of our window from normal to filling up the device it is on.
  294. //    When expanding, we remember the size and coordinates of our window; when
  295. //    shrinking, we use those coordinates to resize and position our window.
  296. //
  297. static void MiniMaxOurDlog( void )
  298. {
  299. static Boolean        isHuge = FALSE;
  300. static Rect            originalGlobalPortRect;    //original port rect in global coordinates
  301. Rect                hugeRect;
  302. GDHandle            aDev;
  303.  
  304.     SetPort(gMainDlogPtr);
  305.  
  306.     if (isHuge)    //it's huge, so shrink it
  307.     {
  308.         HideWindow(gMainDlogPtr);
  309.         MoveWindow(gMainDlogPtr, originalGlobalPortRect.left, originalGlobalPortRect.top, TRUE);
  310.         SizeWindow(gMainDlogPtr,
  311.             originalGlobalPortRect.right - originalGlobalPortRect.left,
  312.             originalGlobalPortRect.bottom - originalGlobalPortRect.top, FALSE);
  313.         ShowWindow(gMainDlogPtr);
  314.  
  315.         isHuge = FALSE;
  316.     }
  317.     else        //it's normal, so expand it
  318.     {
  319.         originalGlobalPortRect = gMainDlogPtr->portRect;
  320.         LocalToGlobalRect(&originalGlobalPortRect);
  321.         
  322.         aDev = GetMaxIntersectDevice(originalGlobalPortRect);
  323.         hugeRect = (**aDev).gdRect;
  324.         
  325.         HideWindow(gMainDlogPtr);
  326.         MoveWindow(gMainDlogPtr, hugeRect.left, hugeRect.top, TRUE);
  327.         SizeWindow(gMainDlogPtr,
  328.             hugeRect.right - hugeRect.left, hugeRect.bottom - hugeRect.top, FALSE);
  329.         ShowWindow(gMainDlogPtr);
  330.         
  331.         isHuge = TRUE;
  332.     }
  333. }//MiniMaxOurDlog
  334.  
  335.  
  336. //____ DoFade __________________________________________________________________________
  337. //
  338. //    Fade out, delay a little while (like we're doing something) and fade back in.
  339. //
  340. static void DoFade( void )
  341. {
  342. #define kFadeSpeed        100
  343.  
  344. long        aLong;
  345.     
  346.     FadeWindowsGDev( gMainDlogPtr, kFadeSpeed, eFade_FadeOutCommand );
  347.     
  348.     Delay(45, &aLong);    //delay 3/4 of a second
  349.     
  350.     FadeWindowsGDev( gMainDlogPtr, kFadeSpeed, eFade_FadeInCommand );
  351.     
  352.  
  353. }//DoFade
  354.  
  355.  
  356. //____ PseudoAlert __________________________________________________________________________
  357. //
  358. //    Presents a dialog posing as an alert. Since it's a dialog, however,
  359. //    we can easily place it where we want. Pass in a rectangle for the
  360. //    dialog to be centered in. Of course, you should already have
  361. //    ParamText'd whatever it is you want to say. Dialog goes away when
  362. //    there's a key press or a mouse click.
  363. //
  364. static void PseudoAlert( Rect *centerRect )
  365. {
  366. DialogPtr            pseudoAlrt;
  367.  
  368.     pseudoAlrt = GetNewDialog( kPseudoAlrtID, NULL, (WindowRef) -1 );
  369.     if (NULL == pseudoAlrt)
  370.         return;
  371.  
  372.     CenterWindowInRect(pseudoAlrt, centerRect, TRUE);
  373.  
  374.     ShowWindow(pseudoAlrt);
  375.     DrawDialog(pseudoAlrt);
  376.     WaitForQuit();
  377.     
  378.     DisposeDialog(pseudoAlrt);
  379.  
  380. }//PseudoAlert